﻿using System;

namespace Aeon.Framework
{

/// <summary>
/// Value object for spatial orientation representation and transformation.
/// 
/// </summary>
public struct Orientation
    {
    // --- Shared:
    
    private static Orientation origin = new Orientation(0,0,0);     // Convenient origin.
    public static Orientation Origin { get { return(origin); } }    // Accessor.    
    
    // --- Fields/Accessors:
    
    private Single x;   public Single xAng { get { return(x); } }   // Component X.
    private Single y;   public Single yAng { get { return(y); } }   // Component Y.
    private Single z;   public Single zAng { get { return(z); } }   // Component Z.

    // --- Constructor:

    public Orientation(Single anX, Single anY) : this(anX,anY,0) { }
    public Orientation(Single anX, Single anY, Single anZ)
        {
        x = y = z = 0;

        x = validate(anX);
        y = validate(anY);
        z = validate(anZ);
        }
        
    // --- Public Methods:

    public void Change(Orientation change)
        {
        x = change.xAng;
        y = change.yAng;
        z = change.zAng;
        }

    public void Transform(Orientation rotations)
        {
        if (rotations.xAng!=0) { x += rotations.xAng; x = validate(xAng); }
        if (rotations.yAng!=0) { y += rotations.yAng; y = validate(yAng); }
        if (rotations.zAng!=0) { z += rotations.zAng; z = validate(zAng); }
        }
        
    // --- Private Methods:

    private Single validate(Single angle)
        {
        if (angle>=0 && angle<=360) return(angle);
        else {
             if (angle>360) angle -= 360;
             else angle += 360;

             return(validate(angle));
             }
        }
        
    }


}
